package edison.persistence;

import java.util.ArrayList;
import java.util.List;

import javax.jcr.nodetype.NodeTypeDefinition;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.OrderColumn;
import javax.persistence.Table;

import edison.utils.Converter;

@Entity(name = "NodeType")
@Table(name = "NodeType")
public class NodeTypeBean {
	@Id
	private String name;

	@ManyToMany(targetEntity = NodeTypeBean.class)
	@OrderColumn
	private List<String> declaredSupertypeNames;
	private boolean isAbstract;
	private boolean isMixin;
	private boolean hasOrderableChildNodes;

	private String primaryItemName;
	private boolean isQueryable;

	@OneToMany(targetEntity = PropertyDefinitionBean.class, mappedBy = "declaringNodeType")
	@OrderColumn
	private List<PropertyDefinitionBean> declaredPropertyDefinitions;
	@OneToMany(targetEntity = NodeDefinitionBean.class, mappedBy = "declaringNodeType")
	@OrderColumn
	private List<NodeDefinitionBean> declaredChildNodeDefinitions;

	public NodeTypeBean() {
	}

	public NodeTypeBean(NodeTypeDefinition ntd) {
		this.name = ntd.getName();
		this.declaredSupertypeNames = Converter.toList(ntd.getDeclaredSupertypeNames());
		this.primaryItemName = ntd.getPrimaryItemName();
		this.isAbstract = ntd.isAbstract();
		this.isMixin = ntd.isMixin();
		this.hasOrderableChildNodes = ntd.hasOrderableChildNodes();
		this.isQueryable = ntd.isQueryable();
		this.declaredPropertyDefinitions = Converter.toPropertyDefinitionBeans(ntd.getDeclaredPropertyDefinitions());
		this.declaredChildNodeDefinitions = Converter.toNodeDefinitionBeans(ntd.getDeclaredChildNodeDefinitions());
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public List<String> getDeclaredSupertypeNames() {
		return declaredSupertypeNames;
	}

	public void setDeclaredSupertypeNames(List<String> declaredSupertypeNames) {
		this.declaredSupertypeNames = declaredSupertypeNames;
	}

	public boolean isAbstract() {
		return isAbstract;
	}

	public void setAbstract(boolean isAbstract) {
		this.isAbstract = isAbstract;
	}

	public boolean isMixin() {
		return isMixin;
	}

	public void setMixin(boolean isMixin) {
		this.isMixin = isMixin;
	}

	public boolean isHasOrderableChildNodes() {
		return hasOrderableChildNodes;
	}

	public void setHasOrderableChildNodes(boolean hasOrderableChildNodes) {
		this.hasOrderableChildNodes = hasOrderableChildNodes;
	}

	public String getPrimaryItemName() {
		return primaryItemName;
	}

	public void setPrimaryItemName(String primaryItemName) {
		this.primaryItemName = primaryItemName;
	}

	public boolean isQueryable() {
		return isQueryable;
	}

	public void setQueryable(boolean isQueryable) {
		this.isQueryable = isQueryable;
	}

	public List<PropertyDefinitionBean> getDeclaredPropertyDefinitions() {
		if (declaredPropertyDefinitions == null)
			declaredPropertyDefinitions = new ArrayList<PropertyDefinitionBean>();
		return declaredPropertyDefinitions;
	}

	public void setDeclaredPropertyDefinitions(List<PropertyDefinitionBean> declaredPropertyDefinitions) {
		this.declaredPropertyDefinitions = declaredPropertyDefinitions;
	}

	public List<NodeDefinitionBean> getDeclaredChildNodeDefinitions() {
		if (declaredChildNodeDefinitions == null)
			declaredChildNodeDefinitions = new ArrayList<NodeDefinitionBean>();
		return declaredChildNodeDefinitions;
	}

	public void setDeclaredChildNodeDefinitions(List<NodeDefinitionBean> declaredChildNodeDefinitions) {
		this.declaredChildNodeDefinitions = declaredChildNodeDefinitions;
	}

	public List<ColumnDescriptor> columns() {
		List<ColumnDescriptor> columns = new ArrayList<ColumnDescriptor>();
		for (PropertyDefinitionBean property : getDeclaredPropertyDefinitions()) {
			columns.add(new ColumnDescriptor(property.getName(), property.getRequiredType()));
		}

		return columns;
	}
}
